package com.yitao.cms.service.expressage;

import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.skipper.base.bean.CommonStatus;
import com.skipper.base.bean.DataOutput;
import com.skipper.base.bean.PagedInput;
import com.skipper.base.bean.PagedOutput;
import com.skipper.base.data.querydsl.PredicateBuilder;
import com.skipper.base.service.GenericEntityService;
import com.yitao.client.constant.ExpressageSubscribeLogEnum;
import com.yitao.client.dto.order.ExpressageSubscribeLogDto;
import com.yitao.client.model.expressage.ServicesCompanyInfoModel;
import com.yitao.client.model.order.ExpressageSubscribeLogModel;
import com.yitao.client.model.order.QExpressageSubscribeLogModel;
import com.yitao.cms.service.order.CmsServicesCompanyInfoService;
import com.yitao.cms.utils.DateUtils;
import com.yitao.cms.utils.ExcelExportUtil;
import com.yitao.cms.vo.expressage.ExpressageSubscribeLogVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Date: 2019/6/12 10:19
 * @Author: Kien
 */
@Service
public class ExpressageSubscribeLogCmsService extends GenericEntityService<ExpressageSubscribeLogModel, ExpressageSubscribeLogDto, QExpressageSubscribeLogModel> {

    @Autowired
    private CmsServicesCompanyInfoService cmsServicesCompanyInfoService;
    @Value("${excel_demo}")
    private String EXCELDEMO;

    private static final Integer TRUE = 0; // 不可以重新订阅
    private static final Integer FALSE = 1; // 可以重新订阅

    public ExpressageSubscribeLogCmsService(EntityManager entityManager) {
        super(entityManager);
    }

    /**
     *
     * 功能描述: 新增订阅日志
     *
     * @param companyCode 物流公司编码
     * @param deliveryNo 快递单号
     * @param returnCode 订阅状态码
     * @param returnCodeValue 订阅状态消息(快递100返回的，没有处理的信息，有些会过长)
     * @return
     * @auther: Kien
     * @date: 2019/6/4 19:28
     */
    @Transactional
    public DataOutput save(String companyCode, String deliveryNo, String returnCode, String returnCodeValue){
        // 如果这个单号半年内存在，则直接修改订阅状态
        Date nowDate = new Date(); // 当前时间
        Date pastDate = DateUtils.getPastDate(180); // 当前日期的180天之前
        List<ExpressageSubscribeLogModel> all = repository.findAll(PredicateBuilder.conjunction()
                .and(() -> Q.deliveryNo.eq(deliveryNo))
                .and(() -> Q.deliveryCompanyCode.eq(companyCode))
                .and(() -> Q.createTime.between(pastDate, nowDate))
                .and(() -> Q.isDelete.eq(false))
                .get());
        if(CollectionUtils.isEmpty(all)) { // 如果为空，直接新增
            logger.info("180天内数据库不存在这个单号，新增");
            ExpressageSubscribeLogModel expressageSubscribeLogModel = new ExpressageSubscribeLogModel();
            expressageSubscribeLogModel.setDeliveryCompanyCode(companyCode); // 快递公司编码
            // 根据快递公司编码获取快递公司全称
            ServicesCompanyInfoModel servicesCompanyInfoByNameabbr = cmsServicesCompanyInfoService.getServicesCompanyInfoByNameabbr(companyCode);
            if(servicesCompanyInfoByNameabbr != null) {
                expressageSubscribeLogModel.setDeliveryCompanyName(servicesCompanyInfoByNameabbr.getCompanyName()); // 快递公司名称
            } else {
                expressageSubscribeLogModel.setDeliveryCompanyName("其他");
            }
            expressageSubscribeLogModel.setCreateTime(new Date()); // 订阅时间
            expressageSubscribeLogModel.setDeliveryNo(deliveryNo); // 物流单号
            expressageSubscribeLogModel.setReturnCode(returnCode); // 订阅状态码
            // 根据状态码获取订阅状态
            expressageSubscribeLogModel.setReturnCodeValue(ExpressageSubscribeLogEnum.EXPRESSAGE_SUBSCRIBE_STATUS.getMsgByCode(returnCode)); // 订阅信息
            expressageSubscribeLogModel.setIsDelete(false);
            ExpressageSubscribeLogModel save = repository.save(expressageSubscribeLogModel);
            return new DataOutput(save);
        } else { // 否则修改当前这批物流单号
            logger.info("180天内数据库存在这个单号，修改这些单号");
            List<Long> list = new ArrayList<>();
            for(ExpressageSubscribeLogModel expressageSubscribeLogModel: all) {
                list.add(expressageSubscribeLogModel.getId());
            }
            if(!CollectionUtils.isEmpty(list)) {
                repository.updateByWhere(PredicateBuilder.conjunction().and(() -> Q.id.in(list)).get(), it -> {
                    it.set(Q.returnCode, returnCode);
                    it.set(Q.returnCodeValue, ExpressageSubscribeLogEnum.EXPRESSAGE_SUBSCRIBE_STATUS.getMsgByCode(returnCode));
                });
            }
            return new DataOutput();
        }

    }

    /**
     *
     * 功能描述: 获取物流单号订阅记录
     *
     * @param companyName 物流公司名称
     * @param deliveryNo 物流单号
     * @param staDate 开始时间
     * @param endDate 结束时间
     * @param pageNo 当前页面
     * @param pageSize 每页显示条数
     * @return
     * @auther: Kien
     * @date: 2019/6/21 18:01
     */
    public PagedOutput<ExpressageSubscribeLogVo> getExpressageSubscribeLogList(String companyName, String deliveryNo, String staDate, String endDate, Integer pageNo, Integer pageSize) {
        PagedInput pagedInput = new PagedInput(pageSize, pageNo);
        List<ExpressageSubscribeLogVo> list = new ArrayList<>();
        try {
            Date staDate1 = null;
            if(!StringUtils.isEmpty(staDate)) {
                staDate1 = DateUtils.parseDateMilliFormat(staDate + " 00:00:00");
            } else {
                staDate1 = DateUtils.parseDateMilliFormat("2019-01-01 00:00:00");
            }
            Date endDate1 = null;
            if(!StringUtils.isEmpty(endDate)) {
                endDate1  = DateUtils.parseDateMilliFormat(endDate + " 23:00:00");
            } else {
                endDate1 = new Date();
            }
            final Date newStaDate = staDate1;
            final Date newEndDate = endDate1;
            PagedOutput<ExpressageSubscribeLogModel> pagedOutput = repository.pagingList(PredicateBuilder.conjunction()
                    .and(() -> Q.isDelete.eq(false))
                    .ifNotNullThenAnd(companyName, () -> Q.deliveryCompanyName.like("%" + companyName + "%"))
                    .ifNotNullThenAnd(deliveryNo, () -> Q.deliveryNo.eq(deliveryNo))
                    .ifTrueThenAnd(newStaDate != null && !"".equals(newStaDate) && newEndDate != null && !"".equals(newEndDate),
                            () -> Q.createTime.between(newStaDate, newEndDate))
                    .get(), pagedInput, new OrderSpecifier<>(Order.DESC, Q.createTime));
            if(pagedOutput != null && pagedOutput.getData() != null) {
                list = pagedOutput.getData().stream().map(it ->{
                    ExpressageSubscribeLogVo expressageSubscribeLogVo = new ExpressageSubscribeLogVo();
                    BeanUtils.copyProperties(it, expressageSubscribeLogVo);
                    expressageSubscribeLogVo.setCreateTimeStr(DateUtils.getDateSecondFormat(it.getCreateTime())); // 格式化时间
                    String returnCode = it.getReturnCode();
                    if(ExpressageSubscribeLogEnum.EXPRESSAGE_SUBSCRIBE_STATUS.SERVER_ERROR.getCode().equals(returnCode)
                        || ExpressageSubscribeLogEnum.EXPRESSAGE_SUBSCRIBE_STATUS.KEY_FAILURE.getCode().equals(returnCode)) {
                        // 如果为服务器错误、key过期或识别不到这个对应的快递公司单号，这个单号可以再次订阅
                        expressageSubscribeLogVo.setIsSubscribe(FALSE); // 未订阅，可以重新订阅
                    } else {
                        expressageSubscribeLogVo.setIsSubscribe(TRUE); // 已订阅，不支持重新订阅
                    }
                    return expressageSubscribeLogVo;
                }).collect(Collectors.toList());
            }
            return new PagedOutput(pagedInput, pagedOutput.getTotalElements(), list);
        } catch (Exception e) {
            logger.error("获取物流订阅记录异常: ");
            logger.error(e.getMessage());
            return new PagedOutput(pagedInput, 0, list);
        }
    }

    /**
     *
     * 功能描述: 根据id查询
     *
     * @param id
     * @return
     * @auther: Kien
     * @date: 2019/6/25 17:58
     */
    public ExpressageSubscribeLogModel getExpressageSubscribeById(Long id) {
        if(null == id) {
            return null;
        }
        return repository.findOne(PredicateBuilder.conjunction().and(() -> Q.id.eq(id)).get());
    }

    /**
     *
     * 功能描述:
     *
     * @param
     * @return
     * @auther: Kien
     * @date: 2019/6/26 11:19
     */
    public void downLoadExcel(HttpServletRequest request, HttpServletResponse response) {
        try {
//            String s = "D:\\yilai\\邮客.xlsx";
//            ExcelExportUtil.downloadExcel(s, request, response);
            ExcelExportUtil.downloadExcel(EXCELDEMO, request, response);
        } catch (Exception e) {
            logger.error("导出Excel模板异常", e);

        }
    }
}
